package event

import (
	"context"
	"errors"
	"gitee.com/simple-set/simple.io/src/socket"
	"log/slog"
)

// SessionState 会话状态
type SessionState int

const (
	Accept     SessionState = iota // 新建连接
	Active                         // 活动连接
	Disconnect                     // 断开连接
)

// Session 会话对象, 每个连接都有唯一会话
type Session struct {
	id        string
	state     SessionState
	ctx       context.Context
	cancel    context.CancelFunc
	Socket    *socket.Socket
	Logger    *slog.Logger
	attribute map[string]any
}

func NewSession(socket *socket.Socket) *Session {
	return NewSessionContext(socket, context.Background())
}

func NewSessionContext(socket *socket.Socket, ctx context.Context) *Session {
	if ctx == nil {
		ctx = context.Background()
	}
	ctx, cancel := context.WithCancel(ctx)
	//logger := slog.Default().With("local", socket.LocalAddr().String(), "remote", socket.RemoteAddr().String())
	logger := slog.Default().With("local", socket.LocalAddr(), "remote", socket.RemoteAddr())
	return &Session{Socket: socket, state: Accept, ctx: ctx, cancel: cancel, Logger: logger, attribute: make(map[string]any)}
}

func (s *Session) State() SessionState {
	return s.state
}

func (s *Session) setState(state SessionState) {
	s.state = state
}

func (s *Session) SetAttr(key string, value any) {
	s.attribute[key] = value
}

func (s *Session) GetAttr(key string) any {
	if attr, ok := s.attribute[key]; ok {
		return attr
	}
	return nil
}

func (s *Session) Close() error {
	if s.Socket == nil {
		return errors.New("socket is nil")
	}
	s.state = Disconnect
	return s.Socket.Close()
}

func (s *Session) Ctx() context.Context {
	return s.ctx
}

func (s *Session) CancelFunc() {
	if s.cancel != nil {
		s.cancel()
	}
}
